#include <stdio.h>

int main(void)
{
    int month, year, i;

    printf("输入月数和年份：\n");
    scanf("%d%d", &month, &year);

    if (month <= 0 || month > 12 || year <= 0 || year > 9999) {
        printf("数据格式错误！！！\n");
        return 0;
    }

    /* 打印日历头 */
    char* m[12] = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"}; // 可使用switch实现打印，效果相同
    printf("      %s月 %d\n", m[month - 1], year);
    printf("日 一 二 三 四 五 六\n");

    /* 计算该月份有多少天 */
    int days = 0;
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            days = 31;
            break;
        case 2:
            days = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 29 : 28;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            days = 30;
            break;
    }

    /* 计算该月份的第一天是星期几 */
    if (month < 3) {
        year--;
        month += 12;
    }
    // 基姆拉尔森计算公式，0表示周日，1~6表示周一到周六
    int week = (1 + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400 + 1) % 7;
    //printf("%d\n", week);

    /* 打印日历 */
    if (week != 0) {
        for (i = 1; i <= week; i++) 
            printf("   "); // 三个空格
    }

    for (i = 1; i <= days; i++) { // 按照天数依次打印
        printf("%2d ", i);
        if (week == 6) // 周六之后则换行
            printf("\n");
        week = (week + 1) % 7;
    }

    printf("\n");

    return 0;
}

